﻿using System;
using System.Diagnostics.Contracts;

namespace OpenLS.Spreadsheet.Formats.Biff.Records
{
    internal class FeatHdrRecord : WorksheetLevelRecord
    {
        private FrtHeader _frtHeader = FrtHeader.Create(2151, FrtFlags.fFrtRef);

        private EnhancedProtection? _protectionData = (EnhancedProtection?) 0x4403;

        private SharedFeatureType isf = SharedFeatureType.ISFPROTECTION;

        public FeatHdrRecord()
        {
        }

        public FeatHdrRecord(SheetProtection protection)
        {
            EnhancedProtection d = 0;

            if (protection.Objects) d |= EnhancedProtection.iprotObjects;
            if (protection.Scenarios) d |= EnhancedProtection.iprotScenarios;
            if (protection.FormatCells) d |= EnhancedProtection.iprotFormatCells;
            if (protection.FormatColumns) d |= EnhancedProtection.iprotFormatColumns;
            if (protection.FormatRows) d |= EnhancedProtection.iprotFormatRows;
            if (protection.InsertColumns) d |= EnhancedProtection.iprotInsertColumns;
            if (protection.InsertRows) d |= EnhancedProtection.iprotInsertRows;
            if (protection.InsertHyperlinks) d |= EnhancedProtection.iprotInsertHyperlinks;
            if (protection.DeleteColumns) d |= EnhancedProtection.iprotDeleteColumns;
            if (protection.DeleteRows) d |= EnhancedProtection.iprotDeleteRows;
            if (protection.SelectLockedCells) d |= EnhancedProtection.iprotSelLockedCells;
            if (protection.Sort) d |= EnhancedProtection.iprotSort;
            if (protection.AutoFilter) d |= EnhancedProtection.iprotAutoFilter;
            if (protection.PivotTables) d |= EnhancedProtection.iprotPivotTables;
            if (protection.SelectUnlockedCells) d |= EnhancedProtection.iprotSelUnlockedCells;
            this._protectionData = d;
        }

        internal override BiffRecordType RecordType
        {
            get { return BiffRecordType.FeatHdr; }
        }

        protected override void ReadContent(BiffReaderContext context, int length)
        {
            _frtHeader.Read(context.Reader);
            isf = (SharedFeatureType) context.ReadUInt16();
            byte reserved = context.ReadByte();
            Contract.Assert(reserved == 1);
            _protectionData = null;
            uint cbHdrData = context.ReadUInt32();
            switch (cbHdrData)
            {
                case 0:
                    break;
                case 0xFFFFFFFF:
                    switch (isf)
                    {
                        case SharedFeatureType.ISFPROTECTION:
                            _protectionData = (EnhancedProtection) context.ReadUInt32();
                            break;
                        case SharedFeatureType.ISFFEC2:
                            break;
                        case SharedFeatureType.ISFFACTOID:
                            throw new NotImplementedException();
                        default:
                            throw new NotSupportedException();
                    }
                    break;
                default:
                    throw new NotSupportedException();
            }
        }

        internal override void Apply(BiffReaderWorksheetContext context)
        {
            if (_protectionData != null)
            {
                EnhancedProtection p = _protectionData.Value;
                SheetProtection protection = context.Worksheet.EnsureProtection();
                protection.Objects = (p & EnhancedProtection.iprotObjects) != 0;
                protection.Scenarios = (p & EnhancedProtection.iprotScenarios) != 0;
                protection.FormatCells = (p & EnhancedProtection.iprotFormatCells) != 0;
                protection.FormatColumns = (p & EnhancedProtection.iprotFormatColumns) != 0;
                protection.FormatRows = (p & EnhancedProtection.iprotFormatRows) != 0;
                protection.InsertColumns = (p & EnhancedProtection.iprotInsertColumns) != 0;
                protection.InsertRows = (p & EnhancedProtection.iprotInsertRows) != 0;
                protection.InsertHyperlinks = (p & EnhancedProtection.iprotInsertHyperlinks) != 0;
                protection.DeleteColumns = (p & EnhancedProtection.iprotDeleteColumns) != 0;
                protection.DeleteRows = (p & EnhancedProtection.iprotDeleteRows) != 0;
                protection.SelectLockedCells = (p & EnhancedProtection.iprotSelLockedCells) != 0;
                protection.Sort = (p & EnhancedProtection.iprotSort) != 0;
                protection.AutoFilter = (p & EnhancedProtection.iprotAutoFilter) != 0;
                protection.PivotTables = (p & EnhancedProtection.iprotPivotTables) != 0;
                protection.SelectUnlockedCells =
                    (p & EnhancedProtection.iprotSelUnlockedCells) != 0;
            }
        }

        internal override void WriteContent(BiffWriterWorkbookContext context)
        {
            _frtHeader.Write(context);
            context.Write((ushort) isf);
            context.Write((byte) 1);
            if (_protectionData != null)
            {
                context.Write(0xFFFFFFFF);
                context.Write((int) _protectionData.Value);
            }
            else
            {
                context.Write((uint) 0);
            }
        }
    }
}